package com.justtalk;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Socket;
import java.net.SocketException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.SourceDataLine;

public class ServerThread extends Thread {
    private Socket socket = null;

    public ServerThread(Socket socket) {
		super("ServerThread");
		this.socket = socket;
    }

    private AudioInputStream audioInputStream;
    private AudioInputStream ais;
    private AudioFormat format;
    private boolean status = true;
    private int port = 50005;
    private int sampleRate = 44100;
    
    public void run() {
		
    	DatagramSocket serverSocket = null;
		try {
			serverSocket = new DatagramSocket(50005);
		} catch (SocketException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

    	/**
    	 * Formula for lag = (byte_size/sample_rate)*2
    	 * Byte size 9728 will produce ~ 0.45 seconds of lag. Voice slightly broken.
    	 * Byte size 1400 will produce ~ 0.06 seconds of lag. Voice extremely broken.
    	 * Byte size 4000 will produce ~ 0.18 seconds of lag. Voice slightly more broken then 9728.
    	 */

    	byte[] receiveData = new byte[4000];

    	format = new AudioFormat(sampleRate, 16, 1, true, false);

    	while (status == true) {
    		DatagramPacket receivePacket = new DatagramPacket(receiveData,
    				receiveData.length);

    		try {
    			serverSocket.receive(receivePacket);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

    		ByteArrayInputStream baiss = new ByteArrayInputStream(
    				receivePacket.getData());

    		ais = new AudioInputStream(baiss, format, receivePacket.getLength());
    		toSpeaker(receivePacket.getData());

    	}
    	
    	
//    	try {
//		    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
//		    BufferedReader in = new BufferedReader(
//					    new InputStreamReader(
//					    socket.getInputStream()));
//	
//		    String inputLine, outputLine;
//		    outputLine = "valod";
//		    out.println(outputLine);
//	
//		    while ((inputLine = in.readLine()) != null) {
//			outputLine = "valod";
//			out.println(outputLine);
//			if (outputLine.equals("Bye"))
//			    break;
//		    }
//		    out.close();
//		    in.close();
//		    socket.close();
//		} catch (IOException e) {
//		    e.printStackTrace();
//		}
    }
    
    public void toSpeaker(byte soundbytes[]) {
        try {
            DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
            SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);

            sourceDataLine.open(format);

            FloatControl volumeControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
            volumeControl.setValue(100.0f);

            sourceDataLine.start();
            sourceDataLine.open(format);

            sourceDataLine.start();

            System.out.println("format? :" + sourceDataLine.getFormat());

            sourceDataLine.write(soundbytes, 0, soundbytes.length);
            System.out.println(soundbytes.toString());
            sourceDataLine.drain();
            sourceDataLine.close();
        } catch (Exception e) {
            System.out.println("Not working in speakers...");
            e.printStackTrace();
        }
    }
}
